﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using AviFile;
namespace Capture
{
    public partial class Form1 : Form
    {
        private Boolean state;
        private Boolean running;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            state = true;
        }


        private void button1_Click_1(object sender, EventArgs e)
        {
            CaptureScreen cap = new CaptureScreen();
            while(state)
            {
                Application.DoEvents();
                pictureBox1.Image = cap.GetDesktopImage();

            }
        }

        private void closeform(object sender, EventArgs e)
        {
            state = false;
        }


        private void setSize_Click(object sender, EventArgs e)
        {
            this.Hide();
            setsize s = new setsize ();
            s.Show();
            this.Show();
            
        }

        

        private void button2_Click(object sender, EventArgs e)
        {

            button1.Enabled=true;
            button2.Enabled=false;
            running = true;

            CaptureScreen cap = new CaptureScreen();

            
            //Bitmap bmp = CaptureScreen.GetDesktopImage();
            Bitmap bmp = cap.GetDesktopImage();
            String filename = "test";
            int fcnt = 0;

            Avi.AVICOMPRESSOPTIONS com = new Avi.AVICOMPRESSOPTIONS();
            com.cbFormat = 0;
            com.cbParms = 0;
            com.dwBytesPerSecond = 0;
            com.dwFlags = 8;
            com.dwInterleaveEvery = 4;
            com.dwKeyFrameEvery = 0;
            com.dwQuality = 7500;
            com.fccHandler = 1668707181;
            com.fccType = 0;
            com.lpFormat = (IntPtr)(0);
            com.lpParms = (IntPtr)0;

            while(running){
                AviManager aviManager = new AviManager(filename + fcnt.ToString()  + ".avi", false);
                VideoStream videoStream = aviManager.AddVideoStream(true, 9, bmp);
                //VideoStream videoStream = aviManager.AddVideoStream(com, 9, bmp);
                

                Bitmap bitmap;

                Boolean loop = true;
                DateTime n = DateTime.Now;

                while (loop)
                {
                    if (DateTime.Now > n.AddSeconds(10)) { loop = false; }

                    bitmap = cap.GetDesktopImage();
                    videoStream.AddFrame(bitmap);
                    Application.DoEvents();
                }

                videoStream.GetFrameClose();

                aviManager.Close();
                fcnt++;

            }

            

            MessageBox.Show("done");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = true;
            running = false;
        }


    }


    /// 
    /// This class shall keep the GDI32 APIs used in our program.
    /// 
    public class PlatformInvokeGDI32
    {

        #region Class Variables
        public const int SRCCOPY = 13369376;

        // i added
        public const int CAPTUREBLT = 1073741824;
        #endregion

        #region Class Functions
        [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
        public static extern IntPtr DeleteDC(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
        public static extern IntPtr DeleteObject(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
        public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
        wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);

        
        #endregion

    }

    /// 
    /// This class shall keep the User32 APIs used in our program.
    /// 
    public class PlatformInvokeUSER32
    {
        #region Class Variables
        public const int SM_CXSCREEN = 0;
        public const int SM_CYSCREEN = 1;
        

        #endregion

        #region Class Functions
        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll", EntryPoint = "GetDC")]
        public static extern IntPtr GetDC(IntPtr ptr);

        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int abc);

        [DllImport("user32.dll", EntryPoint = "GetWindowDC")]
        public static extern IntPtr GetWindowDC(Int32 ptr);

        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

        #endregion
    }

    /// 
    /// This class shall keep all the functionality for capturing the desktop.
    /// 
    public class CaptureScreen
    {

        #region Public Class Functions
        private int width;
        private int height;
        public CaptureScreen()
        {
            width = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);
            height = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CYSCREEN);
        }

        public Bitmap GetDesktopImage()
        {

            //Variable to keep the handle of the btimap.
            IntPtr m_HBitmap;

            //Variable to keep the refrence to the desktop bitmap.
            System.Drawing.Bitmap bmp = null;

            ////In size variable we shall keep the size of the screen.
            //SIZE size;

            //Here we get the handle to the desktop device context.
            IntPtr hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow());

            //Here we make a compatible device context in memory for screen device context.
            IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

            ////We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen.
            //size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);

            ////We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen.
            //size.cy = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CYSCREEN);

            //We create a compatible bitmap of screen size and using screen device context.
            //m_HBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);
            m_HBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, width, height);


            //As m_HBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
            if (m_HBitmap != IntPtr.Zero)
            {
                //Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
                IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, m_HBitmap);

                //We copy the Bitmap to the memory device context.
                //PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);
                //PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY | PlatformInvokeGDI32.CAPTUREBLT);
                PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, width, height, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY | PlatformInvokeGDI32.CAPTUREBLT);

                //We select the old bitmap back to the memory device context.
                PlatformInvokeGDI32.SelectObject(hMemDC, hOld);

                //We delete the memory device context.
                PlatformInvokeGDI32.DeleteDC(hMemDC);
                

                //We release the screen device context.
                PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC);

                //Image is created by Image bitmap handle and assigned to Bitmap variable.
                bmp = System.Drawing.Image.FromHbitmap(m_HBitmap);

                //Delete the compatible bitmap object. 
                PlatformInvokeGDI32.DeleteObject(m_HBitmap);

                return bmp;
            }
            //If m_HBitmap is null retunrn null.
            return null;
        }
        #endregion
    }

    //This structure shall be used to keep the size of the screen.
    //public struct SIZE
    //{
    //    public int cx;
    //    public int cy;
    //}

}

